class vue extends EventTarget {
    constructor(option) {
        super();
        this.option = option;
        this._data = this.option.data;
        // 获取 Dom 节点
        this.el = document.querySelector(this.option.el)
        // 调用函数
        this.observe(this._data);
        this.compileNode(this.el);
    }

    // 监视 data 数据变化，实现数据响应式
    observe(data) {
        let _this = this;
        this._data = new Proxy(data, {
            // 当对象里面的值发生变化的时候，执行set方法
            set(target, prop, newValue) {
                // 监听到data对象中值的改变，然后通过自定义事件修改视图
                console.log(newValue)
                // 定义自定义事件
                let event = new CustomEvent(prop, {
                    detail: newValue
                });

                // 发布自定义事件event------------------这里不太懂
                _this.dispatchEvent(event);

                return Reflect.set(...arguments);
            }
        })
    }


    // 操作该 Dom 节点,处理插值表达式语法
    compileNode(el) {
        // 获取该 Dom 节点的子节点
        let child = el.childNodes;
        // console.log(child) //  NodeList(3) [text, div, text] 换行也是一个text节点
        [...child].forEach(node => {
            // console.log(node)
            if (node.nodeType === 3) {
                // 文本节点
                // 获取文本节点的文本
                let text = node.textContent;
                // 定义正则，匹配 Dom 中的插值表达式
                let reg = /\{\{\s*([^\s\{\}]+)\s*\}\}/g;
                if (reg.test(text)) {
                    let $1 = RegExp.$1;
                    // console.log($1);
                    // 判断data中是否有该值，如果有就将插值表达式替换为 data 中的值
                    this._data[$1] && (node.textContent = text.replace(reg, this._data[$1]));
                    
                    // 监听发布事件------------------这里不太懂
                    this.addEventListener($1, e => {
                        node.textContent = text.replace(reg, e.detail)
                    })
                }
            } else if (node.nodeType === 1) {
                // 元素节点
                // 获取该元素节点上的（自定义）属性集合
                let attr = node.attributes;
                console.log(attr); // NamedNodeMap {0: v-model, v-model: v-model, length: 1}
                // 判断该属性集合中是否含有 v-model
                if (attr.hasOwnProperty('v-model')) {
                    // 获取 v-model属性 里面的值
                    let keyName = attr['v-model'].nodeValue;
                    // console.log(keyName) //test
                    // 将data中定义的值赋值给该 Dom 节点（也就是输入框）的 value 值
                    node.value = this._data[keyName];
                    // 给该 Dom 节点（也就是输入框）添加 input 事件，监听值的变化，使之为响应式
                    node.addEventListener('input', e => {
                        // 将input中的value值赋值给data中相应的值
                        this._data[keyName] = node.value;
                    })
                }
                this.compileNode(node);
            }
        })
    }
}